[GtkApplication] Update for GApplication API changes
authorColin Walters <walters@verbum.org>
Tue, 8 Jun 2010 22:06:03 +0000 (18:06 -0400)
committerColin Walters <walters@verbum.org>
Mon, 14 Jun 2010 22:30:51 +0000 (18:30 -0400)
We now implement "quit" and "action" signals here.

https://bugzilla.gnome.org/show_bug.cgi?id=621003

gtk/gtkapplication.c
gtk/gtkapplication.h

index 6be15a82b11aa8d851ebd0d5e4c2e6689257331a..22660321ab6f5d548ccc324f016ec846b7cacfa7 100644 (file)
@@ -34,6 +34,7 @@
 
 #include "gtkapplication.h"
 #include "gtkmain.h"
+#include "gtkmarshalers.h"
 #include "gtkintl.h"
 #include "gtkprivate.h"
 
@@ -76,6 +77,8 @@ enum
 enum
 {
   ACTIVATED,
+  QUIT,
+  ACTION,
 
   LAST_SIGNAL
 };
@@ -92,14 +95,32 @@ struct _GtkApplicationPrivate
 
 G_DEFINE_TYPE (GtkApplication, gtk_application, G_TYPE_APPLICATION)
 
+static void
+process_timestamp_from_platform_data (GVariant *platform_data)
+{
+  /* TODO - extract timestamp from here, update GDK time */
+}
+
 static gboolean
-gtk_application_default_quit (GApplication *application,
-                              guint         timestamp)
+gtk_application_default_quit (GtkApplication *application)
 {
   gtk_main_quit ();
   return TRUE;
 }
 
+static gboolean
+gtk_application_default_quit_with_data (GApplication *application,
+                                       GVariant     *platform_data)
+{
+  gboolean result;
+
+  process_timestamp_from_platform_data (platform_data);
+  
+  g_signal_emit (application, gtk_application_signals[QUIT], 0, &result);
+
+  return result;
+}
+
 static void
 gtk_application_default_run (GApplication *application)
 {
@@ -128,7 +149,7 @@ gtk_application_default_prepare_activation (GApplication *application,
 }
 
 static void
-gtk_application_default_activated (GApplication *application,
+gtk_application_default_activated (GtkApplication *application,
                                    GVariant     *arguments)
 {
   GtkApplication *app = GTK_APPLICATION (application);
@@ -139,20 +160,27 @@ gtk_application_default_activated (GApplication *application,
 }
 
 static void
-gtk_application_default_action (GApplication *application,
-                                const gchar  *action_name,
-                                guint         timestamp)
+gtk_application_default_action (GtkApplication *application,
+                               const gchar    *action_name)
 {
-  GtkApplication *app = GTK_APPLICATION (application);
   GtkAction *action;
 
-  action = gtk_action_group_get_action (app->priv->main_actions, action_name);
+  action = gtk_action_group_get_action (application->priv->main_actions, action_name);
   if (action)
     {
-      /* TODO set timestamp */
       gtk_action_activate (action);
     }
 }
+                               
+static void
+gtk_application_default_action_with_data (GApplication *application,
+                                         const gchar  *action_name,
+                                         GVariant     *platform_data)
+{
+  process_timestamp_from_platform_data (platform_data);
+
+  g_signal_emit (application, gtk_application_signals[ACTION], g_quark_from_string (action_name));
+}
 
 static GVariant *
 gtk_application_format_activation_data (void)
@@ -377,15 +405,32 @@ gtk_application_run (GtkApplication *app)
  * gtk_application_quit:
  * @app: a #GtkApplication
  *
- * Request the application exit.
- * By default, this method will exit the main loop; see gtk_main_quit().
+ * Request the application exit.  This function invokes
+ * g_application_quit_with_data(), which normally will
+ * in turn cause @app to emit #GtkApplication::quit.
+ *
+ * To control an application's quit behavior (for example, to ask for
+ * files to be saved), connect to the #GtkApplication::quit signal
+ * handler.
  *
  * Since: 3.0
  */
 void
 gtk_application_quit (GtkApplication *app)
 {
-  g_application_quit (G_APPLICATION (app), gtk_get_current_event_time ());
+  GVariantBuilder builder;
+  GVariant *platform_data;
+
+  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
+  g_variant_builder_add (&builder, "{sv}",
+                        "timestamp",
+                        g_variant_new ("u",
+                                       gtk_get_current_event_time ()));
+  platform_data = g_variant_builder_end (&builder);
+    
+  g_application_quit_with_data (G_APPLICATION (app), platform_data);
+
+  g_variant_unref (platform_data);
 }
 
 static void
@@ -495,10 +540,13 @@ gtk_application_class_init (GtkApplicationClass *klass)
   gobject_class->set_property = gtk_application_set_property;
 
   application_class->run = gtk_application_default_run;
-  application_class->quit = gtk_application_default_quit;
-  application_class->action = gtk_application_default_action;
+  application_class->quit_with_data = gtk_application_default_quit_with_data;
+  application_class->action_with_data = gtk_application_default_action_with_data;
   application_class->prepare_activation = gtk_application_default_prepare_activation;
 
+  klass->quit = gtk_application_default_quit;
+  klass->action = gtk_application_default_action;
+
   klass->activated = gtk_application_default_activated;
 
   /**
@@ -522,6 +570,53 @@ gtk_application_class_init (GtkApplicationClass *klass)
                   G_TYPE_NONE, 1,
                   G_TYPE_VARIANT);
 
+  /**
+   * GtkApplication::quit:
+   * @application: the object on which the signal is emitted
+   *
+   * This signal is emitted when a quit is initiated.  See also
+   * the #GApplication::quit-with-data signal which may in
+   * turn trigger this signal.
+   *
+   * The default handler for this signal exits the mainloop of the
+   * application.
+   *
+   * Returns: %TRUE if the signal has been handled, %FALSE to continue
+   *   signal emission
+   */
+  gtk_application_signals[QUIT] =
+    g_signal_new (g_intern_static_string ("quit"),
+                  G_OBJECT_CLASS_TYPE (klass),
+                  G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (GtkApplicationClass, quit),
+                  g_signal_accumulator_true_handled, NULL,
+                  _gtk_marshal_BOOLEAN__VOID,
+                  G_TYPE_BOOLEAN, 0);
+
+  /**
+   * GtkApplication::action:
+   * @application: the object on which the signal is emitted
+   * @name: The name of the activated action
+   *
+   * This signal is emitted when an action is activated. The action name
+   * is passed as the first argument, but also as signal detail, so it
+   * is possible to connect to this signal for individual actions.
+   *
+   * See also the #GApplication::action-with-data signal which may in
+   * turn trigger this signal.
+   *
+   * The signal is never emitted for disabled actions.
+   */
+  gtk_application_signals[ACTION] =
+    g_signal_new (g_intern_static_string ("action"),
+                  G_OBJECT_CLASS_TYPE (klass),
+                  G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED,
+                  G_STRUCT_OFFSET (GtkApplicationClass, action),
+                  NULL, NULL,
+                  g_cclosure_marshal_VOID__STRING,
+                  G_TYPE_NONE, 1,
+                  G_TYPE_STRING);
+                 
   g_type_class_add_private (gobject_class, sizeof (GtkApplicationPrivate));
 }
 
index 6581bcd923776a4d4330cdf294117c7a1e7cac25..7782f0a112ec9cbffc5610e11626654d37b8cada 100644 (file)
@@ -66,8 +66,12 @@ struct _GtkApplicationClass
   GApplicationClass parent_class;
 
   /*< vfuncs >*/
-  void        (* activated)   (GApplication  *application,
-                              GVariant      *args);
+  void        (* activated)   (GtkApplication  *application,
+                              GVariant        *args);
+  void        (* action)      (GtkApplication  *application,
+                              const gchar     *action_name);
+  gboolean    (* quit)        (GtkApplication  *application);
+                              
 
   /* Padding for future expansion */
   void (*_gtk_reserved1) (void);